package org.beetl.core.script;

import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Script;
import org.beetl.core.exception.ErrorInfo;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.core.resource.StringTemplateResourceLoader;

import javax.script.*;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import static javax.script.ScriptContext.ENGINE_SCOPE;
import static javax.script.ScriptContext.GLOBAL_SCOPE;

public class BeetlScriptEngine extends AbstractScriptEngine {
    BeetlScriptEngineFactory factory;
    GroupTemplate groupTemplate;
    StringTemplateResourceLoader loader = new StringTemplateResourceLoader();

    public BeetlScriptEngine(BeetlScriptEngineFactory factory){
        this.factory = factory;
        ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("/");
        Configuration cfg = null;
        try {
            cfg = Configuration.defaultConfiguration();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        cfg.setStatementStart("@");
        cfg.setStatementEnd(null);
        //不得不设置一个模板加载路径
        groupTemplate = new GroupTemplate(resourceLoader, cfg);
    }
    @Override
    public Object eval(String strScript, ScriptContext context) throws ScriptException {
        Script script =  groupTemplate.getScript(strScript,loader);
        script.binding(context.getBindings(ENGINE_SCOPE));
        script.execute();
        if(!script.isSuccess()){
            ErrorInfo errorInfo = script.getErrorInfo();
            throw new BeetlScriptException(errorInfo,(Exception) errorInfo.getCause());
        }
        return script.getResult();
    }

    public Script getScript(String strScript){
        Script script =  groupTemplate.getScript(strScript,loader);
        return script;
    }

    @Override
    public Object eval(Reader reader, ScriptContext context) throws ScriptException {
       throw new UnsupportedOperationException();
    }

    @Override
    public Bindings createBindings() {
          return new SimpleBindings();
    }

    @Override
    public ScriptEngineFactory getFactory() {
        return factory;
    }

    @Override
    protected ScriptContext getScriptContext(Bindings nn) {
        BeetlScriptContext beetlScriptContext =  new BeetlScriptContext();
        beetlScriptContext.setBindings(nn,0);
        return beetlScriptContext;
    }
}
